#include "DataGatherHRF9828.h"
#include <QApplication>
#include "Windows.h"

typedef unsigned int uint;

HINSTANCE g_dllHandle = NULL;

typedef uint (_stdcall *FUNC_FT_ListDevices)(uint pvArg1, char *pvArg2, uint dwFlags);
typedef uint (_stdcall *FUNC_FT_OpenEx)(char *constCStrDeviceDescription, uint Flags, uint *Handle);
typedef uint (_stdcall *FUNC_FT_Write)(uint Handle, byte *Buffer, uint BytesToWrite, uint *BytesWritten);
typedef uint (_stdcall *FUNC_FT_GetQueueStatus)(uint Handle, uint *BytesWaiting);
typedef uint (_stdcall *FUNC_FT_Read)(uint Handle, byte *Buffer, uint BytesToRead, uint *BytesReturned);
typedef uint (_stdcall *FUNC_FT_ResetDevice)(uint Handle);
typedef uint (_stdcall *FUNC_FT_Close)(uint Handle);

FUNC_FT_ListDevices ft_ListDevices = nullptr;
FUNC_FT_OpenEx ft_OpenEx = nullptr;
FUNC_FT_Write ft_Write = nullptr;
FUNC_FT_GetQueueStatus ft_GetQueueStatus = nullptr;
FUNC_FT_Read ft_Read = nullptr;
FUNC_FT_ResetDevice ft_ResetDevice = nullptr;
FUNC_FT_Close ft_Close = nullptr;

DataGatherHRF9828::DataGatherHRF9828()
{
    QString dllPath = QApplication::instance()->applicationDirPath() + "/FTD2XX.dll";    
    dllPath.replace('/', '\\');

    g_dllHandle = LoadLibraryA(dllPath.toLocal8Bit().data());
    if (g_dllHandle)
    {
        ft_ListDevices = (FUNC_FT_ListDevices)GetProcAddress(g_dllHandle, "FT_ListDevices");
        ft_OpenEx = (FUNC_FT_OpenEx)GetProcAddress(g_dllHandle, "FT_OpenEx");
        ft_Write = (FUNC_FT_Write)GetProcAddress(g_dllHandle, "FT_Write");
        ft_GetQueueStatus = (FUNC_FT_GetQueueStatus)GetProcAddress(g_dllHandle, "FT_GetQueueStatus");
        ft_Read = (FUNC_FT_Read)GetProcAddress(g_dllHandle, "FT_Read");
        ft_ResetDevice = (FUNC_FT_ResetDevice)GetProcAddress(g_dllHandle, "FT_ResetDevice");
        ft_Close = (FUNC_FT_Close)GetProcAddress(g_dllHandle, "FT_Close");        
    }
}

DataGatherHRF9828::~DataGatherHRF9828()
{
    if (g_dllHandle)
        FreeLibrary(g_dllHandle);
}

uint DataGatherHRF9828::FT_ListDevices(uint pvArg1, char *pvArg2, uint dwFlags)
{    
    return ft_ListDevices(pvArg1, pvArg2, dwFlags);
}

uint DataGatherHRF9828::FT_OpenEx(char *constCStrDeviceDescription, uint Flags, uint *Handle)
{
    return ft_OpenEx(constCStrDeviceDescription, Flags, Handle);
}

uint DataGatherHRF9828::FT_Write(uint Handle, byte *Buffer, uint BytesToWrite, uint *BytesWritten)
{
    return ft_Write(Handle, Buffer, BytesToWrite, BytesWritten);
}

uint DataGatherHRF9828::FT_GetQueueStatus(uint Handle, uint *BytesWaiting)
{
    return ft_GetQueueStatus(Handle, BytesWaiting);
}

uint DataGatherHRF9828::FT_Read(uint Handle, byte *Buffer, uint BytesToRead, uint *BytesReturned)
{
    return ft_Read(Handle, Buffer, BytesToRead, BytesReturned);
}

uint DataGatherHRF9828::FT_ResetDevice(uint Handle)
{
    return ft_ResetDevice(Handle);
}

uint DataGatherHRF9828::FT_Close(uint Handle)
{
    return ft_Close(Handle);
}
